/*
 * Copyright (C) 2011 Patrik �kerfeldt
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.ddddddl.widget.scrollTab;

import com.ddddddl.zhangben.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;

/**
 * A FlowIndicator which draws circles (one for each view). <br/>
 * Availables attributes are:<br/>
 * <ul>
 * activeColor: Define the color used to draw the active circle (default to
 * white)
 * </ul>
 * <ul>
 * inactiveColor: Define the color used to draw the inactive circles (default to
 * 0x44FFFFFF)
 * </ul>
 * <ul>
 * inactiveType: Define how to draw the inactive circles, either stroke or fill
 * (default to stroke)
 * </ul>
 * <ul>
 * activeType: Define how to draw the active circle, either stroke or fill
 * (default to fill)
 * </ul>
 * <ul>
 * fadeOut: Define the time (in ms) until the indicator will fade out (default
 * to 0 = never fade out)
 * </ul>
 * <ul>
 * radius: Define the circle radius (default to 4.0)
 * </ul>
 */
public class CircleFlowIndicator extends View implements FlowIndicator,
		AnimationListener {
	private static final int STYLE_STROKE = 0;
	private static final int STYLE_FILL = 1;

	private float radius = 4;
	private int fadeOutTime = 0;
	// private final Paint mPaintInactive = new Paint(Paint.ANTI_ALIAS_FLAG);
	private final Paint mPaintActive = new Paint(Paint.ANTI_ALIAS_FLAG);
	private ViewFlow viewFlow;
	private float currentScroll = 0f, currentScrollFinal = 0f;
	private int flowWidth = 0;
	private FadeTimer timer;
	public AnimationListener animationListener = this;
	private Animation animation;
	private boolean mCentered = false;
	private int cuteValue = 0;

	/**
	 * Default constructor
	 * 
	 * @param context
	 */
	public CircleFlowIndicator(Context context) {
		super(context);
		// initColors(0xFFFFFFFF, 0xFFFFFFFF, STYLE_FILL, STYLE_STROKE);
		mPaintActive.setStyle(Style.FILL);

		mPaintActive.setColor(Color.RED);
	}

	/**
	 * The contructor used with an inflater
	 * 
	 * @param context
	 * @param attrs
	 */
	public CircleFlowIndicator(Context context, AttributeSet attrs) {
		super(context, attrs);

		mPaintActive.setStyle(Style.FILL);

		mPaintActive.setColor(context.getResources().getColor(R.color.blue));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onDraw(android.graphics.Canvas)
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// int count = 3;
		// if (viewFlow != null) {
		// count = viewFlow.getViewsCount();
		// }
		//
		// float circleSeparation = 2*radius+radius;
		// //this is the amount the first circle should be offset to make the
		// entire thing centered
		// float centeringOffset = 0;
		//
		// int leftPadding = getPaddingLeft();

		// Draw stroked circles
		// for (int iLoop = 0; iLoop < count; iLoop++) {
		// canvas.drawCircle(leftPadding + radius
		// + (iLoop * circleSeparation) + centeringOffset,
		// getPaddingTop() + radius, radius, mPaintInactive);
		// }

		// float cx = 0;
		//
		// if (flowWidth != 0) {
		// // Draw the filled circle according to the current scroll
		// cx = (currentScroll * (2 * radius + radius)) / flowWidth;
		// }

		// float lineWidth=
		// flowWidth/viewFlow.getViewsCount()==0?getWidth()/viewFlow.getViewsCount():flowWidth/viewFlow.getViewsCount();
		// // float testcx =
		// currentScroll/(viewFlow.getViewsCount()*viewFlow.getViewsCount()*3);
		// float moveWidth = currentScroll/(viewFlow.getViewsCount());
		float lineWidth;
		lineWidth = getWidth() / viewFlow.getViewsCount();
		float view_width = (getRight() - getLeft()) * currentScroll;
		int screen_width;
		// if (ScreenOrient(((Activity) getContext())).equals("1"))
		// {
		screen_width = getDisplayMetrics(((Activity) getContext())).widthPixels; // 屏幕宽度像素
		// }
		// else
		// screen_width = AndroidUtil.getDisplayMetrics(((Activity)
		// getContext())).heightPixels; //屏幕高度像素
		currentScrollFinal = view_width / screen_width;
		float moveWidth = currentScrollFinal / (viewFlow.getViewsCount());

		// The flow width has been upadated yet. Draw the default position
		// canvas.drawCircle(leftPadding + radius + cx+centeringOffset,
		// getPaddingTop()
		// + radius, radius, mPaintActive);
		// Log.i("hcy","test"+lineWidth+"");
		// Log.i("hcy","testcx"+testcx+"");
		// Log.i("hcy","viewFlow"+viewFlow.getViewsCount()+"");
		// Log.i("hcy","getSelectedItemPosition"+viewFlow.getSelectedItemPosition()+"");
		canvas.drawRect(moveWidth + cuteValue, 0, lineWidth + moveWidth
				- cuteValue, getMeasuredHeight(), mPaintActive);
	}

	public static DisplayMetrics getDisplayMetrics(Activity activity) {
		DisplayMetrics displayMetrics = new DisplayMetrics();
		activity.getWindowManager().getDefaultDisplay()
				.getMetrics(displayMetrics);
		return displayMetrics;
	}

	public static String screenOrient(Activity activity) {
		// 取得当前屏幕的方向，如果此�1�7�为-1表示androidManifest.xml没有设置Android:screanOrentation属�1�7�所以这样无法判断屏幕方向�1�7�1�7
		// 可以使用另一种�1�7�路，即长度大于高度的为横屏，否则为竖屏〄1�7
		String landscape = "1";// 横屏静�1�7�常釄1�7
		String portrait = "2";// 竖屏常量
		int width = activity.getWindowManager().getDefaultDisplay().getWidth();// 得到系统显示属�1�7�后得到屏幕宽度
		int height = activity.getWindowManager().getDefaultDisplay()
				.getHeight();// 得到屏幕高度
		return width > height ? portrait : landscape;// 判断
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.taptwo.android.widget.ViewFlow.ViewSwitchListener#onSwitched(android
	 * .view.View, int)
	 */
	@Override
	public void onSwitched(View view, int position) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.taptwo.android.widget.FlowIndicator#setViewFlow(org.taptwo.android
	 * .widget.ViewFlow)
	 */
	@Override
	public void setViewFlow(ViewFlow view) {
		resetTimer();
		viewFlow = view;
		// flowWidth = viewFlow.getWidth();
		flowWidth = getWidth();
		invalidate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.taptwo.android.widget.FlowIndicator#onScrolled(int, int, int,
	 * int)
	 */
	@Override
	public void onScrolled(int h, int v, int oldh, int oldv) {
		setVisibility(View.VISIBLE);
		resetTimer();
		currentScroll = h;
		// flowWidth = viewFlow.getWidth();
		// flowWidth = getWidth();
		invalidate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onMeasure(int, int)
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// setMeasuredDimension(measureWidth(widthMeasureSpec),
		// measureHeight(heightMeasureSpec));

		setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
				measureHeight(heightMeasureSpec));
	}

	/**
	 * Determines the width of this view
	 * 
	 * @param measureSpec
	 *            A measureSpec packed into an int
	 * @return The width of the view, honoring constraints from measureSpec
	 */
	private int measureWidth(int measureSpec) {
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		// We were told how big to be
		if (specMode == MeasureSpec.EXACTLY) {
			result = specSize;
		}
		// Calculate the width according the views count
		else {
			int count = 3;
			if (viewFlow != null) {
				count = viewFlow.getViewsCount();
			}
			result = (int) (getPaddingLeft() + getPaddingRight()
					+ (count * 2 * radius) + (count - 1) * radius + 1);
			// Respect AT_MOST value if that was what is called for by
			// measureSpec
			if (specMode == MeasureSpec.AT_MOST) {
				result = Math.min(result, specSize);
			}
		}
		return result;
	}

	/**
	 * Determines the height of this view
	 * 
	 * @param measureSpec
	 *            A measureSpec packed into an int
	 * @return The height of the view, honoring constraints from measureSpec
	 */
	private int measureHeight(int measureSpec) {
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		// We were told how big to be
		if (specMode == MeasureSpec.EXACTLY) {
			result = specSize;
		}
		// Measure the height
		else {
			result = (int) (2 * radius + getPaddingTop() + getPaddingBottom() + 1);
			// Respect AT_MOST value if that was what is called for by
			// measureSpec
			if (specMode == MeasureSpec.AT_MOST) {
				result = Math.min(result, specSize);
			}
		}
		return result;
	}

	/**
	 * Sets the fill color
	 * 
	 * @param color
	 *            ARGB value for the text
	 */
	public void setFillColor(int color) {
		mPaintActive.setColor(color);
		invalidate();
	}

	// /**
	// * Sets the stroke color
	// *
	// * @param color
	// * ARGB value for the text
	// */
	// public void setStrokeColor(int color) {
	// mPaintInactive.setColor(color);
	// invalidate();
	// }

	/**
	 * Resets the fade out timer to 0. Creating a new one if needed
	 */
	private void resetTimer() {
		// Only set the timer if we have a timeout of at least 1 millisecond
		if (fadeOutTime > 0) {
			// Check if we need to create a new timer
			if (timer == null || timer._run == false) {
				// Create and start a new timer
				timer = new FadeTimer();
				timer.execute();
			} else {
				// Reset the current tiemr to 0
				timer.resetTimer();
			}
		}
	}

	/**
	 * Counts from 0 to the fade out time and animates the view away when
	 * reached
	 */
	private class FadeTimer extends AsyncTask<Void, Void, Void> {
		// The current count
		private int timer = 0;
		// If we are inside the timing loop
		private boolean _run = true;

		public void resetTimer() {
			timer = 0;
		}

		@Override
		protected Void doInBackground(Void... arg0) {
			while (_run) {
				try {
					// Wait for a millisecond
					Thread.sleep(1);
					// Increment the timer
					timer++;

					// Check if we've reached the fade out time
					if (timer == fadeOutTime) {
						// Stop running
						_run = false;
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			animation = AnimationUtils.loadAnimation(getContext(),
					android.R.anim.fade_out);
			animation.setAnimationListener(animationListener);
			startAnimation(animation);
		}
	}

	@Override
	public void onAnimationEnd(Animation animation) {
		setVisibility(View.GONE);
	}

	@Override
	public void onAnimationRepeat(Animation animation) {
	}

	@Override
	public void onAnimationStart(Animation animation) {
	}

	@Override
	public void onOrientationChange() {
		invalidate();
	}

	public void setCuteValue(int value) {
		cuteValue = (int) (value * getContext().getResources()
				.getDisplayMetrics().density);
	}

	public void setCuteValue() {
		setCuteValue(40);
	}

}